package com.tianji.aigc.memory;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import org.springframework.ai.chat.messages.*;

/**
 * 消息转换工具类，提供消息对象与JSON字符串之间的转换功能，主要用于Redis存储格式转换
 */
public class MessageUtil {

    /**
     * 将Message对象转换为Redis存储格式的JSON字符串
     *
     * @param message 需要转换的原始消息对象
     * @return 符合Redis存储规范的JSON字符串
     */
    public static String toJson(Message message) {
        // 将Message对象转换为RedisMessage对象，使用BeanUtil进行属性拷贝
        var redisMessage = BeanUtil.toBean(message, RedisMessage.class);
        
        // 设置消息的文本内容，从原message对象中获取文本并设置到redisMessage中
        redisMessage.setTextContent(message.getText());
        
        // 如果message是AssistantMessage类型，则将其工具调用列表设置到redisMessage中
        if (message instanceof AssistantMessage assistantMessage) {
            redisMessage.setToolCalls(assistantMessage.getToolCalls());
        }
    
        // 如果message是ToolResponseMessage类型，则将其工具响应列表设置到redisMessage中
        if (message instanceof ToolResponseMessage toolResponseMessage) {
            redisMessage.setToolResponses(toolResponseMessage.getResponses());
        }
    
        // 将RedisMessage对象转换为JSON字符串并返回
        return JSONUtil.toJsonStr(redisMessage);
    }

    /**
     * 将Redis存储的JSON字符串反序列化为对应的Message对象
     * @param json Redis存储的JSON格式消息数据
     * @return 对应类型的Message对象
     * @throws RuntimeException 当无法识别的消息类型时抛出异常
     */
    public static Message toMessage(String json) {
        // 将传入的JSON字符串转换为RedisMessage对象，用于后续处理
        var redisMessage = JSONUtil.toBean(json, RedisMessage.class);
        
        // 从RedisMessage中获取消息类型字符串，并转换为MessageType枚举值
        var messageType = MessageType.valueOf(redisMessage.getMessageType());
        
        // 根据消息类型进行分支处理，创建对应的Message实现类实例
        switch (messageType) {
            // 处理系统消息类型：创建SystemMessage实例，仅需要文本内容参数
            case SYSTEM -> {
                return new SystemMessage(redisMessage.getTextContent());
            }
            // 处理用户消息类型：创建UserMessage实例，需要文本内容、媒体列表和元数据参数
            case USER -> {
                return new UserMessage(redisMessage.getTextContent(),
                        redisMessage.getMedia(),      // 获取媒体文件列表
                        redisMessage.getMetadata());  // 获取元数据信息
            }
            // 处理助手消息类型：创建AssistantMessage实例，需要文本内容、元数据和工具调用列表参数
            case ASSISTANT -> {
                return new AssistantMessage(redisMessage.getTextContent(),   // 获取文本内容
                        redisMessage.getMetadata(),    // 获取元数据信息
                        redisMessage.getToolCalls());  // 获取工具调用列表
            }
            // 处理工具响应消息类型：创建ToolResponseMessage实例，需要工具响应列表和元数据参数
            case TOOL -> {
                return new ToolResponseMessage(redisMessage.getToolResponses(), // 获取工具响应列表
                        redisMessage.getMetadata());   // 获取元数据信息
            }
        }
    
        // 如果消息类型不匹配任何已知类型，抛出运行时异常表示转换失败
        throw new RuntimeException("Message data conversion failed.");
    }
}